package org.jeecg.modules.shiro.authc.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.jeecg.modules.shiro.authc.config.DynamicDataSourceContextHolder;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;

/**
 * Aop动态切换多数据源
 * order一定要小于tx:annotation-driven的order，即先执行DynamicDataSourceAspect切面，再执行事务切面，才能获取到最终的数据源
 * @author sakur
 * @since 2022/11/14
 */
@Slf4j
@Aspect
@Component
@Order(-1)
public class DynamicDataSourceAspect {

    /**
     * 切点: 所有配置 DataSource 注解的方法
     */
    @Pointcut("@annotation(org.jeecg.modules.shiro.authc.aspect.DataSource)")
    public void dataSourcePointCut() {
    }

    @Around("dataSourcePointCut()")
    public Object doAround(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        DataSource ds = method.getAnnotation(DataSource.class);
        // 通过判断 DataSource 中的值来判断当前方法应用哪个数据源
        String tenantId = ds.value();

        log.info("Aop切换数据源---->当前租户Id：{}", tenantId);
        DynamicDataSourceContextHolder.clearDataSourceKey();
        if (StringUtils.isEmpty(tenantId)) {
            //这里设置默认的数据源
            DynamicDataSourceContextHolder.setDataSourceKey(DynamicDataSourceContextHolder.DEFAULT_DATASOURCE);
        } else {
            /*这里数据库项目编号来更改对应的数据源*/
            DynamicDataSourceContextHolder.setDataSourceKey(tenantId);
        }
        return point.proceed();
    }

}

